package random

import (
	"encoding/hex"
	"math"
)

// rgb2hsl 颜色空间RGB与HSV(HSL)的转换
func rgb2hsl(rgb []int) []float64 {
	var (
		r       = rgb[0] / 255
		g       = rgb[1] / 255
		b       = rgb[2] / 255
		min     = Min(r, g, b)
		max     = Max(r, g, b)
		delta   = float64(max - min)
		h, s, l float64
	)

	if max == min {
		h = 0
	} else if r == max {
		h = float64(g-b) / delta
	} else if g == max {
		h = 2 + float64(b-r)/delta
	} else if b == max {
		h = 4 + float64(r-g)/delta
	}
	h = Min(h*60, 360)

	if h < 0 {
		h += 360
	}

	l = float64(min+max) / 2

	if max == min {
		s = 0
	} else if l <= 0.5 {
		s = delta / float64(max+min)
	} else {
		s = delta / float64(2-max-min)
	}

	return []float64{h, s * 100, l * 100}
}

func rgb2hsv(rgb []int) []float64 {
	var (
		r       = rgb[0]
		g       = rgb[1]
		b       = rgb[2]
		min     = Min(r, g, b)
		max     = Max(r, g, b)
		delta   = float64(max - min)
		h, s, v float64
	)

	if max == 0 {
		s = 0
	} else {
		s = (delta / float64(max) * 1000) / 10
	}

	if max == min {
		h = 0
	} else if r == max {
		h = float64(g-b) / delta
	} else if g == max {
		h = 2 + float64(b-r)/delta
	} else if b == max {
		h = 4 + float64(r-g)/delta
	}
	h = Min(h*60, 360)

	if h < 0 {
		h += 360
	}
	v = ((float64(max) / 255) * 1000) / 10

	return []float64{h, s, v}
}

func hsl2rgb(hsl []float64) []int {
	var (
		h   = hsl[0] / 360
		s   = hsl[1] / 100
		l   = hsl[2] / 100
		t1  float64
		t2  float64
		t3  float64
		rgb []int
		val float64
	)

	if s == 0 {
		val = l * 255
		return []int{int(val), int(val), int(val)}
	}

	if l < 0.5 {
		t2 = l * (1 + s)
	} else {
		t2 = l + s - l*s
	}
	t1 = 2*l - t2

	rgb = []int{0, 0, 0}
	for i := 0; i < 3; i++ {
		t3 = h + 1/3*-(float64(i)-1)
		if t3 < 0 {
			t3++
		}
		if t3 > 1 {
			t3--
		}

		if 6*t3 < 1 {
			val = t1 + (t2-t1)*6*t3
		} else if 2*t3 < 1 {
			val = t2
		} else if 3*t3 < 2 {
			val = t1 + (t2-t1)*(2/3-t3)*6
		} else {
			val = t1
		}
		rgb[i] = int(val * 255)
	}

	return rgb
}

func hsl2hsv(hsl []float64) []float64 {
	var (
		h  = hsl[0]
		s  = hsl[1] / 100
		l  = hsl[2] / 100
		sv float64
		v  float64
	)
	l *= 2
	s *= Triad(l <= 1, l, 2-l)
	v = (l + s) / 2
	sv = (2 * s) / (l + s)
	return []float64{h, sv * 100, v * 100}
}

func hsv2rgb(hsv []float64) []int {
	var h = hsv[0] / 60
	var s = hsv[1] / 100
	var v = hsv[2] / 100
	var hi = int(math.Floor(h)) % 6

	var f = h - math.Floor(h)
	var p = 255 * v * (1 - s)
	var q = 255 * v * (1 - (s * f))
	var t = 255 * v * (1 - (s * (1 - f)))

	v = 255 * v

	switch hi {
	case 0:
		return []int{int(v), int(t), int(p)}
	case 1:
		return []int{int(q), int(v), int(p)}
	case 2:
		return []int{int(p), int(v), int(t)}
	case 3:
		return []int{int(p), int(q), int(v)}
	case 4:
		return []int{int(t), int(p), int(v)}
	case 5:
		return []int{int(v), int(p), int(q)}
	}
	return nil
}

func hsv2hsl(hsv []float64) []float64 {
	var (
		h  = hsv[0]
		s  = hsv[1] / 100
		v  = hsv[2] / 100
		sl float64
		l  float64
	)

	l = (2 - s) * v
	sl = s * v
	sl /= Triad(l <= 1, l, 2-l)
	l /= 2
	return []float64{h, sl * 100, l * 100}
}

func rgb2hex(a, b, c int) string {
	var out = make([]byte, 6, 6)
	var src []byte = []byte{
		byte(a), byte(b), byte(c),
	}
	hex.Encode(out, src)
	return "#" + string(out)
}

func hex2rgb(a string) []int {
	var out []byte = make([]byte, 3, 3)
	hex.Decode(out, []byte(a[1:]))
	return []int{int(out[0]), int(out[1]), int(out[2])}
}
